home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************
- * FILE: io.c
- * DESC: These are the basic input/output routines. They include
- * disk-handling and keyboard I/O.
- *
- * HISTORY: Created 3/11/1993
- * LAST CHANGED: 5/ 6/1993
- *
- * Copyright (c) 1993 by Scott Anderson
- *
- ****************************************************************/
-
- /* ----------------------INCLUDES----------------------------- */
-
- #include <conio.h>
- #include <stdio.h>
- #include <io.h>
- #include <dos.h> /* for the mouse */
- #include <math.h>
- #include <graph.h>
- #include <malloc.h>
- #include <memory.h>
- #include <string.h>
-
- #include "define.h"
-
- /* ----------------------DEFINES------------------------------ */
-
- /* 0-99 (for tweens) appended to name */
- #define MAX_NAME_SIZE (8-2)
-
- /**** PCX constants ****/
- /* Set top 2 bits for the count bytes */
- #define C0 (0xc0)
- /* The inverse of C0: 0x3f = 63 */
- #define MAX_RUN (0x3f)
- /* Signals a 256 color palette */
- #define PAL_CODE 12
-
- /* -----------------------MACROS------------------------------ */
-
- /* ----------------------TYPEDEFS----------------------------- */
-
- typedef struct {
- char manufacturer;
- char version;
- char encoding;
- char bperpixelperplane;
- unsigned int xmin, ymin, xmax, ymax;
- unsigned int hres, vres;
- char rgbmap[3][16];
- char reserved;
- char nplanes;
- unsigned int bytesperline;
- unsigned int paletteinfo;
- }
- CORE_PCX_HEADER;
-
- typedef struct {
- CORE_PCX_HEADER pcx;
- unsigned char filler[128-sizeof (CORE_PCX_HEADER)];
- }
- HEADER_PCX;
-
- /* ----------------------PROTOTYPES--------------------------- */
-
- char lineAsk(char *name);
- void setTextMode();
- void setGraphicsMode();
- int fixFilename(char *userName, char *fixedName,
- char *extension, int number);
- LINE_LIST *loadLines(char *filename, char *extension);
- int saveLines(char *filename, LINE_LIST *lineList,
- char *extension);
- LINKED_LIST *appendName(LINKED_LIST *head, char *name);
- LINKED_LIST *rootSequence(int argc, char *argv[]);
- int waitForKey();
-
- /* ----------------------GLOBAL DATA-------------------------- */
-
- int CurrentPal = 0; /* ID of current palette */
-
- int Wait = 0;
- int Key;
- int EndWait = OFF;
-
- /* from the last read file, used to save pic */
- static HEADER_PCX Header;
-
- /* Global values set from last picture loaded */
- int Xmin, Ymin, Xmax, Ymax;
-
- /* no file output for NULL name */
- char *OutFilename = NULL;
- long TotalBytes;
-
- int Button;
- int Keystroke;
-
- /*************** The file handling routines *****************/
-
- /*****************************************************************
- * FUNC: int saveScreen(PALETTE *pal)
- *
- * DESC: Save the current screen with the given palette
- *****************************************************************/
-
- int
- saveScreen(PALETTE *pal)
- {
- static int fileCount = 0;
-
- unsigned int byteCount = 0;
- unsigned char lastColor;
- unsigned char color;
- /* The number of bytes in a run */
- unsigned char num;
-
- int index;
- int x, y;
- /* big enough for number & '.PCX' */
- char pcxName[MAX_PATHLEN];
- FILE *fp;
- char *p;
-
- if (!OutFilename) /* no file name on command line */
- return 0;
-
- /* Create a numbered file name for output */
- fileCount++;
- fixFilename(OutFilename, pcxName, EXT_PCX, fileCount);
-
- /* Open the file and print the PCX file header */
- if ((fp = fopen (pcxName, "wb")) == NULL)
- quit (WRITE_OPEN_ERR, pcxName);
- byteCount = fwrite (&Header, 1, sizeof (Header), fp);
- if (byteCount != sizeof (Header))
- quit (WRITE_ERR, pcxName);
-
- /* pack the the screen lines before writing them */
- for (y = Ymin; y <= Ymax; y++) {
- num = 1; /* prime algorithm with the 1st pixel */
- lastColor = _getpixel (Xmin, y);
- for (x = Xmin + 1; x <= Xmax; x++) {
- color = _getpixel (x, y);
- if (color == lastColor) {
- num++; /* Accumulate same-colored pixels */
- if (num == MAX_RUN) {
- byteCount += putBlock (num, lastColor, fp);
- num = 0;
- }
- }
- else { /* This is a pixel of a different color */
- if (num)
- byteCount += putBlock (num, lastColor, fp);
- lastColor = color;
- num = 1;
- }
- }
- /* flush the last byte or batch of bytes on a line */
- if (num)
- byteCount += putBlock (num, lastColor, fp);
- }
- /* Finally, the color palette */
- num = PAL_CODE; /* Write out the palette code byte */
- byteCount += writeByte (&num, fp);
-
- /* Write the color palette */
- for (index = 0; index < COLORS; index++) {
- color = pal->c[index].r << 3;
- byteCount += writeByte (&color, fp);
- color = pal->c[index].g << 3;
- byteCount += writeByte (&color, fp);
- color = pal->c[index].b << 3;
- byteCount += writeByte (&color, fp);
- }
- fclose (fp);
- return byteCount;
- }
-
- /*****************************************************************
- * FUNC: int putBlock(unsigned char num, unsigned char color,
- * FILE *fp)
- *
- * DESC: Write out the 2 or 1 byte block for Run Length Encoding.
- *****************************************************************/
-
- int
- putBlock(unsigned char num, unsigned char color, FILE *fp)
- {
- unsigned int byteCount = 0;
-
- /* Singlet colors with the top 2 bits set could be
- confused with a count, so first write the one-count. */
- if ((num > 1) || ((num == 1) && ((color & C0) == C0))) {
- num |= C0;
- byteCount += writeByte (&num, fp);
- }
- byteCount += writeByte (&color, fp);
- return byteCount;
- }
-
- /*****************************************************************
- * FUNC: int writeByte(unsigned char *byte, FILE *fp)
- *
- * DESC: Write one byte to the file and quit if there is an error.
- *****************************************************************/
-
- int
- writeByte(unsigned char *byte, FILE *fp)
- {
- int count;
-
- count = fwrite (byte, sizeof (char), 1, fp);
- if (count != 1)
- quit (WRITE_ERR, "");
- return count;
- }
-
- /*****************************************************************
- * FUNC: loadPicture (char *filename)
- *
- * DESC: Read a PCX file from the disk into a buffer
- *****************************************************************/
-
- PICTURE *loadPicture (char *filename)
- {
- char pcxName[MAX_PATHLEN];
- FILE *fp;
- int num, count;
- PICTURE *picture;
- unsigned int bytes_read;
- unsigned char byte;
- unsigned char far *bufptr;
-
- fixFilename(filename, pcxName, EXT_PCX, 0);
-
- fp = fopen(pcxName, "rb");
- if (fp == NULL)
- quit (READ_OPEN_ERR, pcxName);
- picture = malloc(sizeof (*picture));
- mustRead(fp, (char *) &Header, sizeof Header);
-
- Xmin = picture->xmin = Header.pcx.xmin;
- Ymin = picture->ymin = Header.pcx.ymin;
- Xmax = picture->xmax = Header.pcx.xmax;
- Ymax = picture->ymax = Header.pcx.ymax;
- picture->tall = Ymax - Ymin + 1;
- picture->wide = Xmax - Xmin + 1;
- picture->pal_id = 0;
- if (picture->tall != MAX_TALL
- || picture->wide != MAX_WIDE
- || Header.pcx.bperpixelperplane != 8
- || Header.pcx.nplanes != 1)
- quit (WRONG_PCX_FILE, pcxName);
- TotalBytes = picture->tall * (long) picture->wide;
- TotalBytes = MIN(TotalBytes, MAX_BYTES);
-
- picture->pixmap = (unsigned char far *)
- _fmalloc((size_t) TotalBytes);
- if (picture->pixmap == NULL)
- return(NULL);
- bufptr = picture->pixmap;
- bytes_read = 0;
-
- while (getBlock(&byte, &count, fp) != EOF) {
- if ((bytes_read += count) > TotalBytes)
- break;
- for (num = 0; num < count; num++)
- *bufptr++ = byte;
- }
- if (Header.pcx.version == 5)
- loadPalette(fp, &picture->pal);
- else
- defaultPalette(&picture->pal);
-
- fclose(fp);
- return picture;
- }
-
- /*****************************************************************
- * FUNC: getBlock (unsigned char *byte, int *count, FILE *fp)
- *
- * DESC: get a Run Length Encoded block. It's either a byte or a
- * string of bytes with a length given by count.
- *****************************************************************/
-
- int
- getBlock (unsigned char *byte, int *count, FILE *fp)
- {
- unsigned char input_byte;
-
- if (fread(&input_byte, sizeof(input_byte), 1, fp) != 1)
- return (EOF);
- *count = 1; /* so far */
- if ((input_byte & C0) == C0) {
- /* Top 2 bits on, data stream to follow */
- /* mask out the byte count */
- *count = input_byte & MAX_RUN;
- mustRead(fp, &input_byte, 1);
- }
- *byte = input_byte; /* return the byte */
- return (0); /* success */
- }
-
- /*****************************************************************
- * FUNC: int mustRead(FILE *fp, char *buf, int n)
- *
- * DESC: Read bytes or quit.
- *****************************************************************/
-
- int
- mustRead(FILE *fp, char *buf, int n)
- {
- int nread;
-
- nread = fread(buf, sizeof(*buf), n, fp);
- if (nread != n)
- quit(READ_ERR, "");
- }
-
- /*****************************************************************
- * FUNC: int loadPalette(FILE *fp, PALETTE *palette)
- *
- * DESC: Go to the end of the file and get the palette
- *****************************************************************/
-
- loadPalette(FILE *fp, PALETTE *palette)
- {
- unsigned char packed_pal[3*COLORS];
- int color, component;
- int red, green, blue;
-
- unsigned char input_byte;
- fseek(fp, -(PALETTE_SIZE+1L), SEEK_END); /* -1 on error */
-
- mustRead(fp, &input_byte, 1);
- if (input_byte != PAL_CODE) {
- printf("The color palette is missing!\n");
- return (ERROR);
- }
- mustRead(fp, packed_pal, sizeof packed_pal);
- for (component = 0, color = 0;
- component < COMPS*COLORS; component += COMPS) {
- palette->c[color].r = packed_pal[component+0]>>3;
- palette->c[color].g = packed_pal[component+1]>>3;
- palette->c[color].b = packed_pal[component+2]>>3;
- color++;
- }
- palette->c[255].r = 0x1f;
- palette->c[255].g = 0x1f;
- palette->c[255].b = 0x1f;
- return (0);
- }
-
- /*****************************************************************
- * FUNC: int freePicture(PICTURE *pic)
- *
- * DESC: Free the memory allocated for this image.
- *****************************************************************/
-
- int
- freePicture(PICTURE *pic)
- {
- _ffree(pic->pixmap);
- free(pic);
- }
-
- /*****************************************************************
- * FUNC: LINE_LIST *loadLines(char *filename, char *extension);
- *
- * DESC: allocate and fill in LINE_LIST structure from file
- *****************************************************************/
-
- LINE_LIST
- *loadLines(char *filename, char *extension)
- {
- char lineName[MAX_PATHLEN];
- FILE *fp;
- char *p;
- LINE_LIST *lineList;
- int number;
- int i;
-
- lineList = malloc(sizeof (*lineList));
- lineList->number = 0;
-
- /* condition the filename to be a line list file name */
- fixFilename(filename, lineName, extension, 0);
- lineList->filename = strdup(lineName);
-
- fp = fopen(lineName, "r");
- if (fp == NULL)
- return lineList;
-
- if (fscanf(fp, "%d\n", &number) != 1
- || number < 1 || number > MAX_LINES) {
- fclose(fp);
- return lineList;
- }
-
- lineList->number = number;
- for(i=0;i<number;i++) {
- if (fscanf(fp, "%d %d %d %d\n",
- &lineList->line[i].p[0].x,
- &lineList->line[i].p[0].y,
- &lineList->line[i].p[1].x,
- &lineList->line[i].p[1].y) != 4)
- quit (READ_CONTENTS_ERR, lineName);
- lineList->line[i].p[0].x = clip(lineList->line[i].p[0].x,
- 0, MAX_WIDE);
- lineList->line[i].p[0].y = clip(lineList->line[i].p[0].y,
- 0, MAX_TALL);
- lineList->line[i].p[1].x = clip(lineList->line[i].p[1].x,
- 0, MAX_WIDE);
- lineList->line[i].p[1].y = clip(lineList->line[i].p[1].y,
- 0, MAX_TALL);
-
- }
- fclose(fp);
- return lineList;
- }
-
- /*****************************************************************
- * FUNC: saveLines(char *filename, LINE_LIST *lineList,
- * char *extension);
- *
- * DESC: save lineList to a file
- *****************************************************************/
-
- saveLines(char *filename, LINE_LIST *lineList, char *extension)
- {
- /* big enough for number & '.PCX' */
- char lineName[MAX_PATHLEN];
- FILE *fp;
- char *p;
- int i;
-
- /* condition the filename to be a line list file name */
- strcpy (lineName, filename);
- strupr (lineName);
- p= strstr(lineName, ".");
- if (p == NULL)
- p = lineName + strlen(lineName);
- strcat(p, extension); /* add extension, it's needed */
-
- fp = fopen(lineName, "w");
- if (fp == NULL)
- quit (WRITE_ERR, lineName);
-
- fprintf(fp, "%d\n", lineList->number);
- for(i=0;i<lineList->number;i++) {
- fprintf(fp, "%d %d %d %d\n",
- lineList->line[i].p[0].x,
- lineList->line[i].p[0].y,
- lineList->line[i].p[1].x,
- lineList->line[i].p[1].y);
- }
- fclose(fp);
- }
-
- /*****************************************************************
- * FUNC: LINKED_LIST *rootSequence(int argc, char *argv[])
- *
- * DESC: Process argument list and return a sequence of pcx files
- *****************************************************************/
-
- LINKED_LIST
- *rootSequence(int argc, char *argv[])
- {
- LINKED_LIST *head = NULL;
- int arg, loaded, i;
- char filename[100];
-
- for (arg = 1; arg < argc; arg++) {
- if (fixFilename(argv[arg], filename, EXT_PCX, 0))
- head = appendName(head, filename);
- else {
- loaded = 0;
- for(i=1;i<MAX_TWEENS;i++) {
- fixFilename(argv[arg], filename, EXT_PCX, i);
- if(_access(filename, 4) == 0) {
- head = appendName(head, filename);
- loaded = 1;
- }
- else if (loaded == 1)
- return head; /* a break in the sequence */
- }
- /* didn't find a sequence, try using EXT_PCX */
- fixFilename(argv[arg], filename, EXT_PCX, 0);
- head = appendName(head, filename);
- }
- }
- return head;
- }
-
- /*****************************************************************
- * FUNC: LINKED_LIST *appendName(LINKED_LIST *head, char *name)
- *
- * DESC: add a data item to the end of the linked list
- *****************************************************************/
-
- LINKED_LIST
- *appendName(LINKED_LIST *head, char *name)
- {
- LINKED_LIST *l;
- LINKED_LIST *end;
-
- l = (LINKED_LIST *) malloc(sizeof (LINKED_LIST));
- l->str = strdup(name);
- l->next = NULL;
-
- if (head == NULL)
- return l;
-
- /* find guy that points to end */
- for(end=head; end->next; end=end->next);
- end->next = l;
- return head;
- }
-
- /*****************************************************************
- * FUNC: int fixFilename(char *userName, char *fixedName,
- * char *extension, int number)
- *
- * DESC: Create a valid filename with correct extension & number.
- * Returns true if the userName had asn extension at end
- *****************************************************************/
-
- int
- fixFilename(char *userName, char *fixedName, char *extension,
- int number)
- {
- char *p;
- char localbuf[100];
- int extensionFound;
-
- strcpy (localbuf, userName);
- p = localbuf + strlen(localbuf) - 4;
- /* extension is there */
- extensionFound = strcmpi(p, extension) == 0;
- if (extensionFound)
- *p = '\0';
- if (number)
- sprintf(fixedName, "%s%d%s", localbuf, number, extension);
- else
- sprintf(fixedName, "%s%s", localbuf, extension);
- return extensionFound;
- }
-
- /*** These are the color and the screen handling routines ***/
-
- /*****************************************************************
- * FUNC: int setPalette(PALETTE *palette)
- *
- * DESC: Set the 256 colors in the palette, using the output ports
- *****************************************************************/
-
- setPalette(PALETTE *palette)
- {
- int color;
-
- for (color = 0; color < COLORS; color++) {
- _outp (0x3c7, color-1);
- _outp (0x3c9, palette->c[color].r << 1);
- _outp (0x3c9, palette->c[color].g << 1);
- _outp (0x3c9, palette->c[color].b << 1);
- }
- }
-
- /*****************************************************************
- * FUNC: int defaultPalette(PALETTE *palette)
- *
- * DESC: Create a gray-scale palette as a default
- *****************************************************************/
-
- defaultPalette(PALETTE *palette)
- {
- int i;
- long j;
- long k;
-
- for (i=0;i<COLORS;i++) {
- j = i & 0x1f;
- palette->c[i].r = palette->c[i].g = palette->c[i].b = j;
- }
- }
- /*****************************************************************
- * FUNC: int displayPicture(PICTURE *picture)
- *
- * DESC: set the video mode & palette, then draw from the buffer
- * to the screen.
- *****************************************************************/
-
- displayPicture(PICTURE *picture)
- {
- int x, y, xb, yb;
-
- if (picture->pal_id == 0) { /* need to define palette */
- picture->pal_id = paletteID(&picture->pal);
- }
- if (CurrentPal != picture->pal_id) {
- setPalette(&picture->pal);
- CurrentPal = picture->pal_id;
- }
- displayNoPal(picture);
- }
-
- /*****************************************************************
- * FUNC: int displayNoPal(PICTURE *picture)
- *
- * DESC: display a picture without messing with the palette
- *****************************************************************/
-
- int
- displayNoPal(PICTURE *picture)
- {
- /* This is the memory address of the VGA screen */
- unsigned char far *screen = (unsigned char far *) 0xa0000000;
- unsigned char far *bufptr = picture->pixmap;
-
- _fmemcpy (screen, bufptr, (unsigned int) MAX_BYTES);
- wait(Wait);
- }
-
- /*****************************************************************
- * FUNC: int paletteID(PALETTE *pal)
- *
- * DESC: return a unique id for each unique palette
- *****************************************************************/
-
- int
- paletteID(PALETTE *pal)
- {
- static PALETTE *definedPals[MAX_FILES];
- static int npals = 0;
- int i;
-
- for (i = 0; i < npals; i++) {
- if (samePal(definedPals[i], pal))
- return i+1;
- }
- definedPals[npals] = pal;
- npals++;
- return npals;
- }
-
- /*****************************************************************
- * FUNC: int samePal(PALETTE *p1, PALETTE *p2)
- *
- * DESC: return 1 if same exact palettes, 0 otherwise
- *****************************************************************/
-
- int
- samePal(PALETTE *p1, PALETTE *p2)
- {
- int index;
-
- for (index = 0; index < COLORS; index++) {
- if (p1->c[index].r != p2->c[index].r) return 0;
- if (p1->c[index].g != p2->c[index].g) return 0;
- if (p1->c[index].b != p2->c[index].b) return 0;
- }
- return 1;
- }
-
- /*****************************************************************
- * FUNC: int drawPalette()
- *
- * DESC: Draw the 256 colors of the current palette in the top
- * left of the screen.
- *****************************************************************/
-
- int
- drawPalette()
- {
- #define BT 4 /* block tall */
- #define BW 6 /* block wide */
-
- int x, y, xb, yb;
-
- for (xb = 0; xb < 16; xb++) {
- for (yb = 0; yb < 16; yb++) {
- for (x = xb*BW; x < (xb*BW + BW); x++) {
- for (y = yb*BT; y < (yb*BT + BT); y++) {
- _setcolor(yb * 16 + xb);
- _setpixel (x, y);
-
- }
- }
- }
- }
- }
-
- /******************** The mouse routines ********************/
-
- /*****************************************************************
- * FUNC: int initMouse()
- *
- * DESC: Initialize the mouse and quit if a driver isn't present.
- *****************************************************************/
-
- #define MOUSE 0x33
-
- int
- initMouse()
- {
- union _REGS regs;
- struct _SREGS sregs;
- regs.x.ax = 0x3533;
- _intdosx(®s, ®s, &sregs);
- if((regs.x.bx | sregs.es ) == 0)
- quit(MOUSE_ERR, "");
- regs.x.ax = 0;
- _int86(MOUSE, ®s, ®s);
- }
-
- /*****************************************************************
- * FUNC: int hideMouse()
- *
- * DESC: Hide the mouse cursor before we draw anything.
- * This use the chunk of screen saved by showMouse.
- *****************************************************************/
-
- int
- hideMouse()
- {
- union _REGS regs;
-
- regs.x.ax = 0x02;
- _int86(MOUSE, ®s, ®s);
- }
-
- /*****************************************************************
- * FUNC: int showMouse()
- *
- * DESC: Redisplay the mouse cursor after drawing something on the
- * screen. Save the chunk of screen under the cursor for
- * hideMouse.
- *****************************************************************/
-
- int
- showMouse()
- {
- union _REGS regs;
-
- regs.x.ax = 0x01;
- _int86(MOUSE, ®s, ®s);
- }
-
- /*****************************************************************
- * FUNC: int mousePos(int *x, int *y)
- *
- * DESC: Return the x,y coordinates of the mouse and any
- * button or keystroke.
- *****************************************************************/
-
- #define KEYHIT 0x0b /* Check the keyboard */
- #define STDIN 0x07 /* Read a char from standard input */
-
- int
- mousePos(int *x, int *y)
- {
- union _REGS regs;
- char *buttons;
- int keystroke;
-
- regs.h.ah = KEYHIT;
- _intdos(®s, ®s);
- keystroke = (regs.h.al == 0xff) ? KEYPRESS : 0;
- if (keystroke) {
- regs.h.ah = STDIN;
- _intdos(®s, ®s); /* STDIN */
- if (Key = regs.h.al == ESC)
- quit(0,""); /* quit on Esc key */
- }
- regs.x.ax = 0x03;
- _int86(MOUSE, ®s, ®s);
- *x = regs.x.cx/2; /* store the x & y coordinates */
- *y = regs.x.dx;
- /* return: 0 = none
- 1 = left
- 2 = right
- 4 = keypress */
- return (Button = (regs.x.bx & 0x03) | keystroke);
- }
-
- /****************** A few utility routines ******************/
-
- /*****************************************************************
- * FUNC: int waitForKey()
- *
- * DESC: Wait for a key to be pressed, then return the key.
- *****************************************************************/
-
- int
- waitForKey()
- {
- int key;
-
- while (!_kbhit());
- key = _getch();
- if (key == ESC)
- quit(0,"");
- return (key); /* clear buffer and return keystroke */
- }
-
- /*****************************************************************
- * FUNC: char lineAsk(char *name)
- *
- * DESC: Ask the users if they want to use the pre-defined lines.
- *****************************************************************/
-
- char
- lineAsk(char *name)
- {
- char c;
-
- setTextMode();
-
- _settextposition(VTAB, HTAB);
- printf ("The picture '%s' has some pre-defined", name);
- _settextposition(VTAB+2, HTAB);
- printf ("control lines. Would you like to use them?");
- _settextposition(VTAB+4, HTAB+8);
- printf ("(Y/N):");
- c = getche();
- if (c == ESC)
- quit(NO_ERROR, "");
- c = toupper(c);
- return c;
- }
-
- /*****************************************************************
- * FUNC: int quitCheck()
- *
- * DESC: Check keyboard. If there is no key waiting, return 0,
- * for OK. If a number from 1-9 is typed, change the wait
- * between frames. Otherwise, the user wants to quit,
- * so return 1.
- *****************************************************************/
-
- int
- quitCheck()
- {
- static int spaceWait = OFF;
-
- if (spaceWait) {
- Key = getch();
- if (Key != ' ')
- spaceWait = OFF;
- }
- else if (_kbhit()) {
- Key = _getch();
- if (Key == ' ') {
- /* turn on space bar stepping */
- spaceWait = ON;
- /* pause for space key */
- Key = _getch();
- }
- if (Key == ESC || Key == 'q' || Key == 'Q')
- return 1; /* a quit key */
- if (Key == 'E' || Key == 'e')
- EndWait ^= ON; /* toggles on and off */
- else if (Key >= '1' && Key <= '9')
- Wait = '9' - Key;
- }
- return 0;
- }
-
- /****************************************************************/
-
- beep()
- {
- printf("\a");
- }
-
- /*****************************************************************
- * FUNC: int clip(int num, int min, int max)
- *
- * DESC: Clip the number to a value between min and max, inclusive.
- *****************************************************************/
-
- int
- clip(int num, int min, int max)
- {
- if (num < min)
- num = min;
- else if (num > max)
- num = max;
-
- return num;
- }
-
- /*****************************************************************
- * FUNC: int waitForTop() and waitForBottom()
- *
- * DESC: These routines wait for the TV scan line to get to the
- * top and the bottom of the screen.
- *****************************************************************/
-
- #define VID_PORT 0x3da
- #define VID_RETRACE 0x8
-
- waitForTop()
- {
- /* wait till retrace ends */
- while(_inp(VID_PORT) & VID_RETRACE);
- }
- waitForBottom()
- {
- /* wait till next retrace starts*/
- while(!(_inp(VID_PORT) & VID_RETRACE));
- }
-
- /*****************************************************************
- * FUNC: int wait(int count)
- *
- * DESC: Wait for a number of screen refreshes, based on count.
- *****************************************************************/
-
- int
- wait (int count)
- {
- int i;
-
- if (!count)
- return 0;
- for (i = 1; i < 2 * count; i++) {
- waitForBottom();
- waitForTop();
- }
- }
-
- /*****************************************************************
- * FUNC: void setGraphicsMode()
- *
- * DESC: Set up the graphics screen
- *****************************************************************/
-
- void
- setGraphicsMode()
- {
- _setvideomode(_MRES256COLOR);
- CurrentPal = 0; /* Force a new palette */
- }
-
- /*****************************************************************
- * FUNC: void setTextMode()
- *
- * DESC: Set the screen to the startup text mode
- *****************************************************************/
-
- void
- setTextMode()
- {
- CurrentPal = 0; /* Force a new palette */
- _setvideomode(_DEFAULTMODE);
- }
-
- /*****************************************************************
- * FUNC: void quit(int err, char *name)
- *
- * DESC: Turn text back on, print the error message and quit.
- *****************************************************************/
-
- void
- quit(ERR err, char *name)
- {
- static char *ErrMess[] = {
- " ",
- "I can't get enough memory. Try turning off some TSR's.",
- "I can't find the file",
- "I can't read the file",
- "I can't open the file",
- "I can't write the file",
- "You must install a mouse driver to run this program.",
- "This is the wrong PCX type - I can't read the file",
- };
-
- setTextMode();
- if (err != NO_ERROR) {
- printf ("Error #%d:\n", err);
- printf ("%s %s\n", ErrMess[err], name);
- exit (err);
- }
- exit (0);
- }
-
-
-